#ifndef NET_SOCKET_H_
#define NET_SOCKET_H_

#include "base/base.h"

#include <sys/types.h>
#include <sys/socket.h>

namespace net {
struct Addr {
    Addr() {
    }
    Addr(const std::string&ip, uint16 port);
    struct sockaddr_in addr;

    const std::string DebugString() const;
};

class Socket {
  public:
    Socket();
    explicit Socket(int32 fd)
        : fd_(fd) {
      CHECK(fd_ != -1);
    }

    static Socket* CreateSocket(int32 fd) {
      return new Socket(fd);
    }

    ~Socket();

    int32 Fd() const {
      return fd_;
    }

    bool Listen(const Addr& addr);

    int32 Accept(Addr* addr);

    bool Connect(const Addr& addr);

    void SetBlock(bool is_block = true) {
      if (!is_block) {
        set_nonblock(fd_);
      } else {
        set_block(fd_);
      }
    }

    void SetRemoteAddr(const Addr& addr) {
      remote_addr_ = addr;
    }
    void SetLocalAddr(const Addr& addr) {
      local_addr_ = addr;
    }
    const Addr& RemoteAddr() const {
      return remote_addr_;
    }
    const Addr& LocalAddr() const {
      return local_addr_;
    }

  private:
    int fd_;
    struct Addr local_addr_;
    struct Addr remote_addr_;

    DISALLOW_COPY_AND_ASSIGN(Socket);
};
}
#endif
